Kwik.Page.include("Kwik.Collections.DelimitedString.js");
Kwik.Page.include("Kwik.Data.RowCollection.js");
Kwik.Page.include("Kwik.Data.Pager.js");
Kwik.Page.include("Kwik.Data.Command.js");
Kwik.Page.include("Kwik.Data.Source.js");

/**
* Asynchronous data connector which uses JSON as data structure
* @extends Kwik.AsyncRequest
* @requires Kwik.AsyncRequest
* @requires Kwik.Data.Source
* @requires Kwik.Data.Pager
* @requires Kwik.Data.Command
* @requires Kwik.Data.RowCollection
* @requires Kwik.Collections.DelimitedString
* @constructor
* @created 12:37 AM 7/29/2009
* @modified 12:38 AM 7/29/2009
*/
Kwik.Data.Connector = function(config)
{
	/** @ignore */
	Kwik.Utility.extend(this, "Kwik.AsyncRequest");
	this.__class.push("Kwik.Data.Connector");


	/** String containing name value pairs @type String */
	this.connectionString = "";
	/** Result row collection @type Kwik.Data.RowCollection */
	this.result = new Kwik.Data.RowCollection();

	this.open = function Connector_open(connectionstring)
	{
		connectionstring = connectionstring || this.connectionString;
		if(!Kwik.Type.isString(connectionstring)){throw new Error("Kwik.Data.Connector.open: Connectionstring is missing.");}

		this.connectionString = connectionstring;
		var dstr = new Kwik.Collections.DelimitedString({value: connectionstring, ignoreCase:true});
		this.url = dstr.getItem("data source", "");
		this.name = dstr.getItem("name", null);
		this.password = dstr.getItem("password", null);
		this.method = "POST";
		if(this.url == ""){throw new Error("Kwik.Data.Connector.open: Can't open connection, 'data source' not defined.");}
		
		this.requestHeaders["Content-Type"] = "application/x-www-form-urlencoded";
		this.Kwik$AsyncRequest.open();
	};

	/** Get the schema from the remote source */
	this.getSchema = function()
	{
		this.clearEvent("oncomplete");
		this.attachEvent("oncomplete", new Function(this.referenceString() + "._schemaComplete()"));
		this.send("$command=$schema");
		Kwik.Page.log.write("Kwik.Data.Connector.getSchema: Request sent.");
	};

	this.execute = function Connector_execute(command)
	{
		this.clearEvent("oncomplete");
		if(!Kwik.Type.isKwikType(command, "Kwik.Data.Command")){throw new Error("Kwik.Data.Connector.execute: Incorrect parameter specified.");}

		this.fireEvent("onbeforeexecute", [command]);
		this.send(this.getSendData(command));
		
	};

	this.getSendData = function(command)
	{
		var table = command.getTable();
		var ret = [];
		if(table != null){ret.push("$table=", escape(table.name));}
		ret.push("$command=" + escape(command.name));
		var arr = command.parameters.toArray();
		for(var i=0; i<arr.length; i++)
		{
			ret.push(escape(arr[i].name) + "=" + escape(arr[i].value));
		}
		return ret.join("&");
	};

	/** Configure this connector object @type Kwik.Data.ConnectorConfig */
	this.configure = function Connector_configure(config)
	{
		config = this.Kwik$AsyncRequest.configure(config);
		if(config.connectionString){this.connectionString = config.connectionString;}
		return config;
	};

	this._schemaComplete = function()
	{
		Kwik.Page.log.write("Kwik.Data.Connector._schemaComplete: Request completed, building source.");
		var obj = null;

		eval("obj = " + this.responseText);
		var src = new Kwik.Data.Source();

		src.connectionString = this.connectionString;
		var tables = obj["tables"];

		if(typeof tables == "object")
		{

			Kwik.Page.log.write("Kwik.Data.Connector._schemaComplete: Adding tables.");
			for(t in tables)
			{
				if(tables[t] == Object.prototype[t] || typeof tables[t] != "object"){continue;}

				var table = src.tables.add(t, new Kwik.Data.Table({name:t}));

				var columns = tables[t].columns;
				if(typeof columns == "object")
				{
					for(c in columns)
					{
						if(columns[c] == Object.prototype[c] || typeof columns[c] != "object"){continue;}
						table.columns.add(c, new Kwik.Data.Column(columns[c]));
					}
				}

				var commands = tables[t].commands;
				if(typeof commands == "object")
				{
					for(c in commands)
					{
						if(commands[c] == Object.prototype[c] || typeof commands[c] != "object"){continue;}
						var command = table.commands.add(c, new Kwik.Data.Command({name: c}));
							
						var parameters = commands[c].parameters;
						if(typeof parameters == "object")
						{
							for(p in parameters)
							{
								if(parameters[p] == Object.prototype[p] || typeof parameters[p] != "object"){continue;}
								command.parameters.add(p, new Kwik.Data.Parameter(parameters[p]));
							}
						}
					}
				}

				var pager = tables[t].pager;
				if(typeof pager == "object")
				{
					table.pager = new Kwik.Data.Pager(pager);
				}
			}
		}

		this.fireEvent("onschemacomplete", [src]);
	};

	this.onschemacomplete = function(source){};

	/** @ignore */
	this.main = function(config)
	{
		if(config){this.configure(config);}
	}; this.main(config);
};

/**
* Data connector configuration object
* @constructor
* @created 12:21 AM 7/29/2009
* @modified 12:21 AM 7/29/2009
*/
Kwik.Data.ConnectorConfig = function()
{
	/** String containing name value pairs @type String */
	this.connectionString = "";
};
